﻿VMController = function (vm) {
    this.vm = vm;
    vm.SetEventHandler(this);
};

VMController.prototype.PropertyChanged = function (propertyName)
{
    if (propertyName == "StackChanged")
        this.vm_stackChanged();
    else if (propertyName == "IPChanged")
        this.vm_ipChanged();
    else if (propertyName == "MemoryChanged")
        this.vm_memoryChanged();
    else if (propertyName == "ActiveChanged")
        this.vm_activeChanged();
};


VMController.prototype.vm_stackChanged = function () {
    var newStackHeight = this.vm.State.Stack.GetSize();
    if (newStackHeight > this.stackHeight) {
        var top = this.vm.State.Stack.Top();
        $("#executionStack tr:first").after("<tr><td>" + (newStackHeight - 1).toString() + "</td><td>" + top.Type + "</td><td>" + top.Value + "</td></tr>");
    }
    else if (newStackHeight < this.stackHeight) {
        $("#executionStack tr:nth-child(2)").detach();
    }
    this.stackHeight = newStackHeight;
};

VMController.prototype.vm_ipChanged = function () {
    var ip = this.vm.GetIP();
    if (ip != null)
    {
        $("#instructionPointer").text(ip);
        $("#currentInstruction").text(this.vm.CurrentInstruction());    
    }
    else
    {
        $("#instructionPointer").text("");
        $("#currentInstruction").text("");            
    }
};

VMController.prototype.vm_memoryChanged = function () {
    this.clearMemory();
    for (var i = 0; i < this.vm.State.Locals.Length(); i++)
    {
        var slot = this.vm.State.Locals.Get(i);
        if (slot)
            $("#localMemory tr:last").after("<tr><td>" + i + "</td><td>" + slot.Type + "</td><td>" + slot.Value + "</td></tr>");        
    }
};

VMController.prototype.vm_activeChanged = function () {
    var active = this.vm.IsActive();
    if (active)
        $("#nextButton").removeAttr("disabled");
    else
        $("#nextButton").attr("disabled", "disabled");
};

VMController.prototype.clearStack = function () {
    $("#executionStack tr:gt(0)").detach();
};

VMController.prototype.clearMemory = function () {
    $("#localMemory tr:gt(0)").detach();
};

VMController.prototype.RunProgram = function (sourceCode) {
    this.vm.Console.WriteHeader();
    
    var simpleParser = new SimpleILParser();
    var commands = simpleParser.Assemble(sourceCode);
    this.vm.LoadProgram(commands);

    this.clearStack();
    this.clearMemory();
    
    if ($("#continuousCheckBox").is(":checked")) {
        this.vm.Continuous = true;
        try 
        {
            this.vm.ExecuteProgram();
        } 
        catch(e) 
        {
            this.vm.Console.WriteLine(e.message);
            this.vm.Console.WriteLine(e.stack);
        } 
    }
    else {
        this.vm.Continuous = false;
    }
};

VMController.prototype.StepOne = function () {
    var continuous = $("#continuousCheckBox").is(":checked");
    try 
    {
        if (continuous)
        {
            this.vm.Continuous = true;
            this.vm.Resume();
        }
        else
            this.vm.StepOne();
    } 
    catch(e) 
    {
        this.vm.Console.WriteLine(e.message);
        this.vm.Console.WriteLine(e.stack);
    } 
};